package cn.xiuxius.embedded.command.clean;


import cn.xiuxius.embedded.command.TaskCommand;
import cn.xiuxius.embedded.config.EasyYamlConfig;
import cn.xiuxius.embedded.keil.KeilProjectXML;
import lombok.extern.slf4j.Slf4j;
import picocli.CommandLine;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.util.Comparator;
import java.util.concurrent.Callable;
import java.util.stream.Stream;

@CommandLine.Command(name = "clean",
        description = "Clean command",
        mixinStandardHelpOptions = true
)
@Slf4j
public class CleanCommand implements Callable<Integer> {

    @CommandLine.ParentCommand
    private TaskCommand taskCommand;

    @Override
    public Integer call() {
        if (taskCommand == null) {
            CommandLine.usage(this, System.out);
            return 1;
        }

        if (taskCommand.prepare() != 0) {
            return 1;
        }

        EasyYamlConfig config = taskCommand.getConfig();
        KeilProjectXML keilProjectXML = taskCommand.getKeilProjectXML();
        log.info("----------------------- Clean Start -----------------------");
        boolean success = doClean(config, keilProjectXML);
        if (!success) {
            return 1;
        }
        log.info("----------------------- Clean End -----------------------");
        return 0;
    }


    private boolean doClean(EasyYamlConfig config, KeilProjectXML keilProjectXML) {
        Path keilRootPath = Path.of(config.getKeilProject().getRootPath());
        Path listingPath = keilRootPath.resolve(keilProjectXML.getListingPath());
        Path objectsPath = keilRootPath.resolve(keilProjectXML.getOutputDirectory());
        boolean success = true;
        success &= deleteDirectoryNio(listingPath);
        success &= deleteDirectoryNio(objectsPath);
        log.info("Clean completed: {}", success ? "success" : "fail");
        return success;
    }

    /**
     * 使用 Java NIO 安全删除目录（包括子文件和空目录）
     * @return true 删除成功或目录不存在，false 删除失败
     */
    private boolean deleteDirectoryNio(Path path) {
        if (!Files.exists(path)) {
            return true;
        }
        try (Stream<Path> walk = Files.walk(path)) {
            walk.sorted(Comparator.reverseOrder())  // 先删文件，再删空目录
                    .forEach(p -> {
                        try {
                            Files.delete(p);  // 删除文件或空目录
                        } catch (NoSuchFileException e) {
                            // 文件已被其他线程删除（可忽略）
                        } catch (IOException e) {
                            log.error("Failed to delete: {} {}", p, e.getMessage());
                        }
                    });
            return true;
        } catch (IOException e) {
            log.error("Failed  to delete directory: {} {}", path, e.getMessage());
            return false;
        }
    }


}
